package com.netty.server;

import com.netty.data.Msg;
import com.netty.message.MessageProtocol;
import com.netty.protobuf.MessageProto;
import com.netty.service.TaskService;
import com.netty.util.GsonUtil;
import com.netty.util.SpringUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.springframework.stereotype.Component;


/**
 * @author
 */
@Component
@ChannelHandler.Sharable
public class ServerChannelHandler extends ChannelInboundHandlerAdapter {

    private String beat = "hello";
    private int count = 0;
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception {
        //传输自定义协议数据
        // 用于获取客户端发来的数据信息
//        MessageProtocol body = (MessageProtocol) obj;
//        byte[] content = body.getContent();
//        if(beat.equals(new String(content))){
//            System.out.println("client :"+ new String(body.getContent()));
//            // 会写数据给客户端
//            String str = "ok";
//            byte[] bytes = str.getBytes();
//            MessageProtocol response = new MessageProtocol(bytes.length,
//                    bytes);
//            ctx.writeAndFlush(response);
//        }else{
//            count ++;
//            System.out.println("client :"+count+","+ new String(body.getContent()));
//        }

        //传输字符窜数据
//        String socketString = ctx.channel().remoteAddress().toString();
//        if(beat.equals(obj.toString())){
//            ctx.writeAndFlush("ok");
//        }else{
//            System.out.println("client:"+socketString+":"+obj.toString());
//        }
        //传输实体类数据
        MessageProto.Message message = (MessageProto.Message) obj;
        String socketString = ctx.channel().remoteAddress().toString();
        if(beat.equals(message.getContent())){
            System.out.println("client:"+socketString+":"+message.getContent());
            MessageProto.Message pong = MessageProto.Message.newBuilder().setContent("ok").build();
            ctx.writeAndFlush(pong);
        }else {
            count ++;
            System.out.println("服务端接收客户端"+socketString+"的数据：");
            System.out.println(count+","+message.getId()+","+message.getContent());
//            Msg msg = GsonUtil.GsonToBean(content, Msg.class);
//            msg.setRemoteaddress(socketString);
//            TaskService taskService = SpringUtil.getBean(TaskService.class);
//            taskService.insertMsg(msg);
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {

        String socketString = ctx.channel().remoteAddress().toString();
        if (obj instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) obj;
            //如果读通道处于空闲状态，说明没有接收到心跳命令
            if (IdleState.READER_IDLE.equals(event.state())) {
                if (event.state() == IdleState.READER_IDLE) {
                    System.out.println("客户端: " + socketString + " READER_IDLE 读超时");
                } else if (event.state() == IdleState.WRITER_IDLE) {
                    System.out.println("客户端: " + socketString + " WRITER_IDLE 写超时");
                } else if (event.state() == IdleState.ALL_IDLE) {
                    System.out.println("客户端: " + socketString + " ALL_IDLE 总超时");
                }
            }
        } else {
            super.userEventTriggered(ctx, obj);
        }
    }


    /**
     * @Description 客户端连接时执行，将客户端信息保存到Map中
     * @param ctx
     **/
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("通道启动");
        super.channelActive(ctx);
        System.out.println("客户端 " + getRemoteAddress(ctx) + " 链接成功");
        //往channel map中添加channel信息
        NettyServer.map.put(getIPString(ctx), ctx.channel());
    }

    /**
     * @Description 客户端断开连接时执行，将客户端信息从Map中移除
     * @param ctx
     * @Date 2019/8/28 14:22
     * @Author wuyong
     * @return
     **/
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //删除Channel Map中的失效Client
        System.out.println("移除客户端通道："+getIPString(ctx));
        NettyServer.map.remove(getIPString(ctx));
        ctx.close();

    }
    /**
     * 异常处理
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }


    /**
     * 获取client对象：ip+port
     *
     * @param ctx
     * @return
     */
    public String getRemoteAddress(ChannelHandlerContext ctx) {
        String socketString = "";
        socketString = ctx.channel().remoteAddress().toString();
        return socketString;
    }

    /**
     * 获取client的ip
     *
     * @param ctx
     * @return
     */
    public String getIPString(ChannelHandlerContext ctx) {
        String ipString = "";
        String socketString = ctx.channel().remoteAddress().toString();
        int colonAt = socketString.indexOf(":");
        ipString = socketString.substring(1, colonAt);
        return ipString;
    }


}
